#include "audioencodetask1.h"
#include <qDebug>
#include <dlfcn.h> /* 必须加这个头文件 */
AudioEncodeTask::AudioEncodeTask(Receive_handler *pHandler):m_pHandler(pHandler)
{
    outfile = NULL;

    Enc_AudioCodec = avcodec_find_encoder(AV_CODEC_ID_AAC);

    qDebug(QString("avcodec_find_encoder:").toLocal8Bit().data());
    if (!Enc_AudioCodec)
    {
        //qDebug(QString("p_avcodec_find_decoder执行失败:").append(QString::number((long)videoCodec)).toLocal8Bit().data());
        return  ;
    }

    qDebug(QString("avcodec_alloc_context3:").toLocal8Bit().data());
    Enc_AvContext = avcodec_alloc_context3(Enc_AudioCodec);
    if (!Enc_AvContext)
    {
            fprintf(stderr, "Could not allocate video codec context\n");
            return  ;
    }

    qDebug(QString("avcodec_alloc_context3 end:").toLocal8Bit().data());
    Enc_AvContext->codec_id   = AV_CODEC_ID_AAC;//
    Enc_AvContext->codec_type = AVMEDIA_TYPE_AUDIO;
    Enc_AvContext->sample_fmt = AV_SAMPLE_FMT_S16;  //16位
    Enc_AvContext->sample_rate= 8000;               //8000 采样
    Enc_AvContext->channel_layout=AV_CH_LAYOUT_MONO;//单声道
    Enc_AvContext->channels = 1;                    //单声道
    //Enc_AvContext->bit_rate = 64000;

    if (avcodec_open2(Enc_AvContext, Enc_AudioCodec,NULL) < 0)
    {
        qDebug(QString("编码器打开失败！:").toLocal8Bit().data());

        printf("编码器打开失败！\n");
        return ;
    }

    pCacheFrame = avcodec_alloc_frame();

    pCacheFrame->nb_samples= Enc_AvContext->frame_size;

    pCacheFrame->format= Enc_AvContext->sample_fmt;

    out_buffer_size = av_samples_get_buffer_size(NULL, 1,1024,AV_SAMPLE_FMT_S16, 1);

    qDebug(QString("out_buffer_size :").append(QString::number((long)out_buffer_size)).toLocal8Bit().data());

    out_buffer = (uint8_t *)av_malloc(out_buffer_size * 2);

    avcodec_fill_audio_frame(pCacheFrame, Enc_AvContext->channels, Enc_AvContext->sample_fmt,(const uint8_t*)out_buffer, out_buffer_size, 1);

    m_pack_num1 = 0;
    m_pack_num2 = 0;
}

AudioEncodeTask::~AudioEncodeTask()
{
    if(Enc_AvContext)
    {
       avcodec_close(Enc_AvContext);
    }

    if(pCacheFrame)
    {
         av_free(pCacheFrame);
         pCacheFrame = 0;
    }

    if(out_buffer)
    {
        av_free(out_buffer);
    }

//    if(outfile)
//        fclose(outfile);
}

int AudioEncodeTask::close()
{
    std::string str("");

    int nthread  =thr_count();

    for (int i =0 ;i<nthread ;i++)
        putq(str);

    wait();
    return 0;
}

bool AudioEncodeTask::receive_handler(char *data, int size)
{
    m_pack_num1 ++ ;
    //qDebug(QString("AudioEncodeTask::receive_handler size:").append(QString::number((long)size)).toLocal8Bit().data());
    putq(std::string(data,size));
    return true;
}

int AudioEncodeTask::svc()
{
    std::string str ="";

     AVPacket pkt;
     av_init_packet(&pkt);
     while(getq(str))
     {
         if (str=="")
            break;

         m_pack_num2 ++;

         int data_size = str.length();
         if(data_size == out_buffer_size)
         {
            memcpy(out_buffer,str.data(),out_buffer_size);
            int got_frame=0;
            int ret = avcodec_encode_audio2(Enc_AvContext, &pkt,pCacheFrame, &got_frame);
            if(ret < 0)
            {
              break;
            }
            qDebug(QString("avcodec_encode_audio2 !< 0:").toLocal8Bit().data());

            if (got_frame==1)
            {
                qDebug(QString("receive_handler(pkt.data,pkt.size):").append(QString::number((long)pkt.size)).toLocal8Bit().data());

                if(m_pHandler)
                    m_pHandler->receive_handler((char*)pkt.data,pkt.size);
              //ret = av_write_frame(pFormatCtx, &pkt);
            }
         }
     }
     return 0;
}

